#include <stdio.h>
#include <sys/types.h>       
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/ioctl.h>

#include "bloom_filter.h"

main(int argc, char **argv) 
{ 
  int sid; 
  in_addr_t group_addr;
  const int TTL=64;

  ssize_t msglen; 
  struct sockaddr_in dst_addr; 
  socklen_t addrlen; 
  char buf[1024]; 
  int port; 
  int seqno = 0; 
  int * seqno_ptr = buf + sizeof(bloom_filter_t) ; 
  int interval = 5; 

  struct ifreq ifreq; 

  static struct ip_mreq mreq; 
  u_char loop = 1;

  if (argc <= 4) { 
    printf("%s multicast_group port interval bloom_filter\n", argv[0]); 
    exit(1); 
  }
        
  bzero(&dst_addr, sizeof(dst_addr)); 

  group_addr  =  inet_addr(argv[1]);
  port = atoi(argv[2]);   
  interval = atoi(argv[3]); 
  
  hex_string_to_bloom_filter(argv[4], buf);  
  mreq.imr_multiaddr.s_addr = group_addr; 
  mreq.imr_interface.s_addr = INADDR_ANY; 

  dst_addr.sin_family = AF_INET; 
  dst_addr.sin_addr.s_addr = group_addr  ; 
  dst_addr.sin_port = htons(port); 

  sid = socket(PF_INET, SOCK_DGRAM, 0); 
  if (sid < 0) { 
    perror("Error when creating socket"); 
    exit(1); 
  }
  
  strncpy(ifreq.ifr_name, "eth1", sizeof("eth1")); 

  if (ioctl(sid, SIOCGIFADDR, &ifreq) < 0) { 
    perror("Error when calling ioctl"); 
    exit(1); 
  }
  memcpy(&mreq.imr_interface, &((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr, 
				sizeof(struct in_addr));


  setsockopt(sid, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));


  //printf("Setting source address  to  %s\n", inet_ntoa(src_addr.sin_addr)); 

 
  /*
  if (setsockopt(sid, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { 
    perror("Error when setsockopt"); 
    exit(1); 
  }
  */
  
  setsockopt(sid, IPPROTO_IP, IP_MULTICAST_TTL, &TTL, sizeof(TTL));
  *seqno_ptr = htonl(seqno); 
  
  while(1) { 
    printf("Sending %d bytes to  group %s at port %d (seqno=%d)\n", sizeof(buf),  inet_ntoa(mreq.imr_multiaddr), port, seqno);     
    msglen =  sendto(sid, buf,  sizeof(buf), 0, &dst_addr, sizeof(dst_addr) );
    if (msglen < 0) { 
      perror("Error when send"); 
      continue; 
    }
    sleep(interval);
    *seqno_ptr = htonl(++seqno);  
  }      
  

}
